// src/main/expressServer.ts
import express from "express";
import http from "http";
import path from "path";
import fs from "fs/promises";
import multer from "multer";
import cors from "cors";
import { getSystemRootDir } from "./utils";
import axios from "axios";
import { FileStorage, type StorageData } from "./FileStorage";
// 导入路由模块
import memoryRoutes from "./routes/memoryRoutes";
import diaryRoutes from "./routes/diaryRoutes";
import sessionRoutes from "./routes/sessionRoutes";

let server: http.Server | null = null;
let uploadDir: string;

// 确保目录存在
async function ensureDirExists(dir: string) {
  try {
    await fs.access(dir);
  } catch {
    await fs.mkdir(dir, { recursive: true });
  }
}

export const createUploadDirectory = async (env: any) => {
  if (env === "development") {
    // 开发环境：使用 __dirname
    uploadDir = path.join(__dirname, "../data/", "uploads");
    console.log(`[开发环境] 上传目录路径: ${uploadDir}`);
  } else {
    // 生产环境：基于客户端安装包所在磁盘创建 MemoryUploads 到系统根目录
    uploadDir = path.join(getSystemRootDir(), ".MemoryData/", "uploads");
    console.log(`[生产环境] 将创建上传目录于: ${uploadDir}`);
  }

  // 确保上传目录存在
  await fs.mkdir(uploadDir, { recursive: true }).catch((error: any) => {
    console.error(`创建上传目录失败: ${(error as Error).message}`);
    throw error; // 重新抛出错误以便调用者可以处理
  });
};

export async function startExpressServer() {

  new FileStorage();

  const expressApp = express();
  const port = 32068;

  // 允许跨域请求
  expressApp.use(cors());
  
  // 解析 JSON 请求体，增加请求体大小限制到50MB
  expressApp.use(express.json({ limit: '50mb' }));

  // 获取按日期组织的上传目录
  async function getDateBasedUploadDir(baseDir: string): Promise<any> {
    const date = new Date();
    const year = date.getFullYear().toString();
    const month = (date.getMonth() + 1).toString().padStart(2, "0");
    const day = date.getDate().toString().padStart(2, "0");
    const dateDir = path.join(baseDir, year, month, day);
    await ensureDirExists(dateDir);

    return dateDir;
  }

  // 配置 multer 存储
  const storage = multer.diskStorage({
    destination: async (req, file, cb) => {
      // 动态生成日期目录
      const dateDir = await getDateBasedUploadDir(uploadDir);
      cb(null, dateDir);
    },
    filename: (req, file, cb) => {
      // 生成唯一文件名：时间戳+随机数+原始扩展名
      const uniqueSuffix = Date.now() + "-" + Math.round(Math.random() * 1e9);
      const ext = path.extname(file.originalname);
      cb(null, file.fieldname + "-" + uniqueSuffix + ext);
    },
  });
  // 配置 multer
  const upload = multer({
    storage: storage, // 使用自定义存储
    limits: {
      fileSize: 50 * 1024 * 1024, // 限制文件大小为 50MB
    },
    // fileFilter: (req, file, cb) => {
    //   // 只允许图片格式文件
    //   const allowedTypes = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif'];
    //   if (!allowedTypes.includes(file.mimetype)) {
    //     const error = new Error('只允许上传图片格式文件');
    //     return cb(error as any, false);
    //   }
    //   cb(null, true);
    // }
  });

  expressApp.get("/", (req, res) => {
    res.send("Hello from Electron Express!");
  });

  // 添加路由日志以便调试
  expressApp.use("/api", (req, res, next) => {
    console.log(`API Request: ${req.method} ${req.originalUrl}`);
    next();
  });

  // 注册路由模块
  expressApp.use("/api", memoryRoutes);
  expressApp.use("/api", diaryRoutes);
  expressApp.use("/api", sessionRoutes);

  // 获取所有存储数据
  expressApp.get("/api/storage", async (req, res) => {
    try {
      const fileStorage = new FileStorage();
      await fileStorage.init();
      const allData = await fileStorage.getAll();
      res.json({
        code: 200,
        data: allData,
        message: "success",
      });
    } catch (error) {
      console.error("获取存储数据失败:", error);
      res.status(500).json({
        code: 500,
        error: "获取存储数据失败",
      });
    }
  });

  // 还原存储数据
  expressApp.post("/api/storage/restore", async (req, res) => {
    try {
      const restoreData: StorageData = req.body;

      const fileStorage = new FileStorage();
      await fileStorage.init();

      // 直接写入新数据
      await fileStorage.writeData(restoreData);

      res.json({
        code: 200,
        message: "数据还原成功",
      });
    } catch (error) {
      console.error("还原存储数据失败:", error);
      res.status(500).json({
        code: 500,
        error: "还原存储数据失败",
      });
    }
  });

  // 添加404处理中间件
  expressApp.use("/api", (req, res) => {
    console.log(`404 Not Found: ${req.method} ${req.originalUrl}`);
    res.status(404).json({
      code: 404,
      error: `API endpoint not found: ${req.method} ${req.originalUrl}`,
    });
  });

  // 文件上传路由
  expressApp.post("/upload", upload.single("file"), (req: any, res: any) => {
    if (!req.file) {
      return res.status(400).json({ error: "No file uploaded" });
    }

    const relativePath = path.relative(uploadDir, req.file.path);
    res.json({
      code: 200,
      message: "File uploaded successfully",
      data: {
        url: `/uploads/${relativePath.replace(/\\/g, "/")}`,
        filename: req.file.filename,
        originalname: req.file.originalname,
      },
    });
  });

  // 静态文件服务，用于访问上传的文件
  expressApp.use("/uploads", express.static(uploadDir));

  // 获取所有上传的文件
  expressApp.get("/getAllUploads", async (req: any, res: any) => {
    try {
      // 递归读取 uploadDir 下的所有文件
      const getAllFiles = async (
        dirPath: string
      ): Promise<Array<{ name: string; path: string }>> => {
        const files: Array<{ name: string; path: string }> = [];
        const entries = await fs.readdir(dirPath, { withFileTypes: true });

        for (const entry of entries) {
          const fullPath = path.join(dirPath, entry.name);
          const relativePath = path.relative(uploadDir, fullPath);

          if (entry.isDirectory()) {
            const subFiles = await getAllFiles(fullPath);
            files.push(...subFiles);
          } else {
            files.push({
              name: entry.name,
              path: relativePath.replace(/\\/g, "/"),
            });
          }
        }

        return files;
      };

      const files = await getAllFiles(uploadDir);
      res.json({
        code: 200,
        message: "Files retrieved successfully",
        data: files,
      });
    } catch (error) {
      console.error("Error reading upload directory:", error);
      res.status(500).json({
        code: 500,
        error: "Failed to retrieve files",
      });
    }
  });

  // 删除文件接口
  expressApp.delete("/deleteFile", async (req: any, res: any) => {
    try {
      const { filePath } = req.body;

      if (!filePath) {
        return res.status(400).json({
          code: 400,
          error: "File path is required",
        });
      }

      // 构建完整的文件路径
      const fullPath = path.join(uploadDir, ...filePath.split("/"));

      // 检查文件是否存在
      try {
        await fs.access(fullPath);
      } catch {
        return res.status(404).json({
          code: 404,
          error: "File not found",
        });
      }

      // 删除文件
      await fs.unlink(fullPath);

      // 重新获取文件列表
      const getAllFiles = async (
        dirPath: string
      ): Promise<Array<{ name: string; path: string }>> => {
        const files: Array<{ name: string; path: string }> = [];
        const entries = await fs.readdir(dirPath, { withFileTypes: true });

        for (const entry of entries) {
          const fullPath = path.join(dirPath, entry.name);
          const relativePath = path.relative(uploadDir, fullPath);

          if (entry.isDirectory()) {
            const subFiles = await getAllFiles(fullPath);
            files.push(...subFiles);
          } else {
            files.push({
              name: entry.name,
              path: relativePath.replace(/\\/g, "/"),
            });
          }
        }

        return files;
      };

      const files = await getAllFiles(uploadDir);

      res.json({
        code: 200,
        message: "File deleted successfully",
        data: files,
      });
    } catch (error) {
      console.error("Error deleting file:", error);
      res.status(500).json({
        code: 500,
        error: "Failed to delete file",
      });
    }
  });

  //调用 qwen-plus 实现聊天
  expressApp.post("/chat-stream", async (req: any, res: any) => {
    const { prompt, qwenPlusApiKey, history = [] } = req.body;

    if (!prompt) {
      return res.status(400).json({ error: "Missing prompt" });
    }

    // 限制历史记录数量，只保留最近的10条消息（5轮对话）
    const MAX_HISTORY_LENGTH = 10;
    const recentHistory = history.slice(-MAX_HISTORY_LENGTH);

    // 检查历史记录是否已包含当前用户输入
    // 如果客户端已经发送了system消息，则使用客户端的system消息，否则使用默认的
    const hasSystemMessage = recentHistory.some((msg: any) => msg.role === "system");
    let messages = hasSystemMessage 
      ? [...recentHistory]
      : [
          { role: "system", content: "你是一个中文 AI 助手。" },
          ...recentHistory,
        ];

    // 如果历史记录末尾没有当前prompt，则添加
    const lastMessage = recentHistory[recentHistory.length - 1];
    if (
      !lastMessage ||
      lastMessage.role !== "user" ||
      lastMessage.content !== prompt
    ) {
      messages.push({ role: "user", content: prompt });
    }

    try {
      const response = await axios({
        method: "post",
        url: "https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions",
        headers: {
          Authorization: "Bearer " + qwenPlusApiKey,
          "Content-Type": "application/json",
        },
        data: {
          model: "qwen-plus",
          messages,
          stream: true,
        },
        responseType: "stream",
      });

      // 设置响应头（标准文本流）
      res.setHeader("Content-Type", "text/plain; charset=utf-8");
      res.setHeader("Transfer-Encoding", "chunked");

      // 逐块读取数据并发送给前端
      response.data.on("data", (chunk: any) => {
        // 处理流式响应数据
        const lines = chunk.toString().split("\n").filter(Boolean);

        for (const line of lines) {
          try {
            // 处理SSE格式的数据
            if (line.startsWith("data: ")) {
              const data = line.slice(6);
              if (data === "[DONE]") {
                res.end();
                return;
              }

              const json = JSON.parse(data);
              const content = json.choices?.[0]?.delta?.content;
              if (content) {
                res.write(content);
              }
            }
          } catch (e) {
            console.warn("⚠️ 跳过非 JSON 行:", line);
          }
        }
      });

      response.data.on("end", () => res.end());
      response.data.on("error", (err: any) => {
        console.error("❌ DashScope 流异常:", err.message);
        res.end();
      });
    } catch (err: any) {
      console.error("❌ 接口调用失败:", err.message);
      res.status(500).end("Internal Server Error");
    }
  });

  server = expressApp.listen(port, () => {
    console.log(`Express server running at http://localhost:${port}`);
  });
}

export function stopExpressServer() {
  if (server) {
    server.close(() => {
      console.log("Express server stopped");
    });
    server = null;
  }
}
